﻿// Spun AJAX Framework
// Copyright (C) 2008 Blake Hegerle
//
// This program is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with this program.  If not, see <http://www.gnu.org/licenses/>.

using Formality.Parsing.ContextFree;

namespace Formality.TestFramework.Parsing.ContextFree
{
    public class TestGrammars
    {
        public static Grammar<string> MakeAStarBStar()
        {
            var S = new Nonterminal<string>("S");

            S.add(() => "");
            S.add((t)'a', S, (t)'b',
                 (a, s, b) => a + s + b);

            return Grammar.New(S);
        }

        public static Grammar<object> MakeExpressionGrammar()
        {
            var expr = new Nonterminal<object>("expr");
            var term = new Nonterminal<object>("term");
            var primary = new Nonterminal<object>("primary");
            var @int = new Nonterminal<object>("int");
            var digit = new Nonterminal<object>("digit");

            expr.add(expr, (t)'+', term, (a, b, c) => null);
            expr.add(term, a => null);

            term.add(term, (t)'*', primary, (a, b, c) => null);
            term.add(primary, a => null);

            primary.add((t)'(', expr, (t)')', (a, b, c) => null);
            primary.add(@int, a => null);

            @int.add(digit, a => a);
            @int.add(digit, @int, (a, b) => null);

            for (var c = '0'; c <= '9'; c++)
                digit.add((t)c, d => null);

            return Grammar.New(expr);
        }

        public static object s0() { return null; }
        public static object s1<T>(T o) { return null; }
        public static object s2<T1, T2>(T1 o1, T2 o2) { return null; }
        public static object s4<T1, T2, T3, T4>(T1 o1, T2 o2, T3 o3, T4 o4) { return null; }

        static TestGrammars()
        {
            s0();
            s1(0);
            s2(0, 0);
            s4(0, 0, 0, 0);
        }
    }
}
